(function ($) {
    $.fn.yqComboGrid = function (opts, param) {
        if (typeof opts == 'string') {
            return $.fn.yqComboGrid.methods[opts](this, param);
        }

        $this = this;
        var opt;
        if ($this.data("yqtype") == "yqComboGrid") {
            var $uniqueID = $this.attr("ID");
            var opts_ = $.extend({}, options($this));
            destroy($this);
            $this = $("#" + $uniqueID);
            opt = $.extend(opts_, opts);

            delete opt.toolbar;
        }
        else {
            opt = $.extend({}, $.fn.yqComboGrid.defaults, opts);
            var $uniqueID = $this.attr("ID");
            if ($uniqueID === undefined || $uniqueID === null || $uniqueID == "") {
                $uniqueID = $.getUniqueID();
                $this.attr("ID", $uniqueID);
            }
        }

        if (opt.width === undefined && $this.width() > 0) {
            opt.width = $this.width();
        }
        else if (typeof opt.width != "undefined") {
            $this.width(opt.width);
        }

        //转换编辑尺寸
        if (typeof opt.editModeW == "string") {
            var r_str = opt.editModeW.substring(opt.editModeW.length - 1, opt.editModeW.length);
            if (r_str == "%") {
                var wSacle = parseInt(opt.editModeW.substring(0, opt.editModeW.length - 1));
                opt.editModeW = parseInt(wSacle * $(window).width() / 100);
            } else {
                opt.editModeW = parseInt(opt.editModeW);
            }
        }
        if (typeof opt.editModeH == "string") {
            var r_str = opt.editModeH.substring(opt.editModeH.length - 1, opt.editModeH.length);
            if (r_str == "%") {
                var wSacle = parseInt(opt.editModeH.substring(0, opt.editModeH.length - 1));
                opt.editModeH = parseInt(wSacle * $(window).height() / 100);
            } else {
                opt.editModeH = parseInt(opt.editModeH);
            }
        }

        //---前处理，兼容输入设置错误
        if (opt.bindingKeyId == "") {
            opt.bindingKeyId = null;
        }
        if (opt.bindingValue == "") {
            opt.bindingValue = null;
        }
        if (opt.pKeyId == "") {
            opt.pKeyId = null;
        }
        if (opt.pKeyValue == "") {
            opt.pKeyValue = null;
        }

        if (opt.isPage && opt.move) {   //如果有分页，不能排序
            opt.move = false;
        }

        opt.columns = [[]]; //表头对象
        opt.defaultEdit = opt.isEdit;
        opt.where = "";      //当前查询
        opt.prewhere = "*";  //上一个查询
        opt.fk_rows = [];  //外键集合
        //-------------------------

        opt.innerEdit_ = true;//外部删除、注销等操作附加按钮，默认是系统操作

        //bindding
        opt.afterBinding = false;
        //组件加载结束
        opt.onload = false;
        //组件进程执行中
        opt.running = false;

        //变量信息
        $this.data("combogrid_opt", opt);
        $this.data("yqtype", "yqComboGrid");
        //init_text($this);

        init_combogrid($this);
    };

    $.fn.yqComboGrid.defaults = {
        ajaxUrl: "/_db.html", //ajax地址
        //width: 200,         
        dbname: null,
        tbname: null,
        tempno: -1,  //模板no

        keyId: "sid", //关键字段
        displayMember: "name",          //显示字段
        bindingKeyId: null,
        bindingValue: null,
        pKeyId: null,
        pKeyValue: null,

        addWhere: "",                   //额外条件
        order: "",     //排序

        titles: [],  //数据列配置对象                   //数据列配置对象
        data: {
            "error": 0,
            "info": "ok",
            "pageNumber": 1,
            "pageSize": 5,
            "pageCount": 0,
            "recordCount": 0,
            rows: []
        },

        //查询相关
        rownumbers: true,                //显示行号
        isPage: true,
        pageNo: 1,
        pageSize: 10,
        pageList: [5, 10, 20, 30, 40, 50],

        loadData: false, //初始化加载数据

        isSeek: true,
        seekNo: -1,                      //查询模板编码  displayType=2生效
        seekModeW: 500,                  //模态编辑器宽度 格式为 800（数字）
        seekModeH: 350,                  //模态编辑器高度 格式为 600（数字）

        //操作相关
        isEdit: true, //可编辑
        copy: true,
        add: true,
        upp: true,
        del: true,
        isdel: false, //可注销
        isdel_field: "isdel", //注销使用的字段
        isdelEdit: true, //注销是否可编辑
        move: false, //可移动
        state: false,   //可状态编辑
        state_field: "state",//状态字段
        wflock: false,        //可流程控制
        editLinks: [],  //显示的链接菜单
        editMenus: [],  //显示在其它中的菜单
        popMenuWidth: 150,     //右键菜单第一层宽度

        editAlert: true,  //删除、注销提醒
        editLoadData: false, //添加、修改后更新数据库数据

        editMode: 2,   //1、2、3 弹出编辑模态窗体,4-弹出模态窗体，独立编辑文件
        editType: 1,    //editMode=1,2,3时  1:属性编辑模式  2:form编辑模式
        editModeW: 850, //模态编辑器宽度 格式为 800（数字）
        editModeH: 650, //模态编辑器高度 格式为 600（数字）
        editMaximiz: false, //最大化显示
        editModeNo: -1, //编辑模板
        loadDefault: false,   //加载默认值
        blankTag: "*",        //值不能为空，标题附加标记

        moveModeW: 800, //模态编辑器宽度 格式为 800（数字）
        moveModeH: 600, //模态编辑器高度 格式为 600（数字）
        moveModeNo: 1,  //移动模板



        defaultVal: null,

        beforeBindingTitle: function (columns, callback) {
            callback(columns);
        }, //标题绑定前
        afterBindingTitle: function () { }, //标题绑定后

        beforeLoadData: function (opts, callback) {   //opts：查询参数，data：未null时，默认查询；不是null，外部查询
            var data = null;
            callback(opts, data);
        },

        beforeSetdata: function (data, callback) {
            callback(data)
        }, //绑定数据之前
        afterSetdata: function (data) { }, //绑定数据之后
        onChange: function (newValue, newRow, oldValue, oldRow) {

        },
        uppActionState: function (value, row, callback) {     //操作节点状态处理接口
            callback(true);
        },

        btnAction: function (action, params, callback) {   //头部菜单执行动作，返回true为执行默认选择操作
            callback(true);
        },
        onBeforeShowEdit: function (titles, action, row, callback) {      //add/upp/move 编辑执行前
            callback(true, titles, row);      //true 执行编辑
        },
        beforeDataAction: function (d_rows, callback) {    //修改之前，true 执行
            callback(true, d_rows);
        },
        afterDataAction: function (rows, res) {    //修改之后，true 默认界面处理

        },
    };

    $.fn.yqComboGrid.methods = {
        options: function (jq) {
            return options(jq);
        },
        destroy: function (jq) {
            destroy(jq);
        },
        isEdit: function (jq, tf) {
            isEdit(jq, tf);
        },
        resize: function (jq, width) {
            resize(jq, width);
        },

        toolbar: function (jq) {
            return options(jq).toolbar;
        },
        btnEnable: function (jq, id) {
            var toolbar = options(jq).toolbar;
            if (typeof toolbar != "undefined") {
                toolbar.yqEditMenu("enable", id);
            }
        },
        btnDisable: function (jq, id) {
            var toolbar = options(jq).toolbar;
            if (typeof toolbar != "undefined") {
                toolbar.yqEditMenu("disable", id);
            }
        },

        setBindingValue: function (jq, bindingValue) {
            var opt = options(jq);
            opt.bindingValue = bindingValue;
            opt.prewhere = "*";

            uppActionState(jq);
        },
        setPKeyValue: function (jq, pKeyValue) {
            var opt = options(jq);
            opt.pKeyValue = pKeyValue;
            opt.prewhere = "*";
        },

        loadData: function (jq) {
            loadData(jq);
        },

        setData: function (jq, data) {
            setData(jq, data);
        },

        clearData: function (jq) {
            var $object = jq;
            setData($object, { rows: [] });
        },

        seek: function (jq, where) { //查询数据
            if (where === undefined) {
                where = "";
            }
            seek(jq, where);
        },
        reSeek: function (jq) { //重新加载数据
            reSeek(jq);
        },

        appendRow: function (jq, row) { //添加行
            appendRow_data(jq, row)
        },
        updateRow: function (jq, param) { //{"index":1,"row":{}}  修改行            
            if (param.index === undefined) {
                var opt = options(jq);
                var rows = jq.combogrid("grid").datagrid("getRows");
                for (var i = 0; i < rows.length; i++) {
                    if (rows[i][opt.keyId] == param[opt.keyId]) {
                        var _param = { "index": i, "row": $.extend({}, param) };
                        param = _param;
                        break;
                    }
                }
            }

            updateRow_data_(jq, param.row, param.index)
        },
        deleteRow: function (jq, i) {  //删除行
            if (typeof i == "number") {
                deleteRow_data_(jq, i)
            } else if (typeof i === 'object' && i !== null) {
                var opt = options(jq);
                var rows = jq.combogrid("grid").datagrid("getRows");
                for (var _i = 0; _i < rows.length; _i++) {
                    if (rows[_i][opt.keyId] == i[opt.keyId]) {
                        deleteRow_data_(jq, _i);
                        break;
                    }
                }
            }
        },

        addRow: function (jq, row) { //添加行(进行数据库数据添加处理)
            rowEdit($(jq[0]), "add", row);
        },
        uppRow: function (jq, row) { //修改行(进行数据库数据修改处理)
            rowEdit($(jq[0]), "upp", row);
        },
        delRow: function (jq, row) {  //删除行(进行数据库数据删除处理)
            var $object = jq;
            options($object).innerEdit_ = false;
            del_run($object, row);
        },

        clear: function (jq) {
            setValue(jq, null);
        },
        setValue: function (jq, value) {
            setValue(jq, value);
        },
        getValue: function (jq) {
            return getValue(jq);
        },
        setSelected: function (jq, row) {
            setSelected(jq, row);
        },

        getSelected: function (jq) {
            return getSelected(jq);
        },
        getRows: function (jq) {
            var rows = jq.combogrid("grid").datagrid("getRows");
            return rows;
        }
    };

    function options($object) {
        return $object.data("combogrid_opt");
    }

    function form_load($object) {
        var opt = options($object);
        opt.onload = true;

        isEdit($object, opt.isEdit);

        opt.afterBindingTitle.call($object);

        $object.textbox("options").onResize = function (width, height) {
            opt.width = width;
            isEdit($object, opt.isEdit);
        };
    }

    function resize($object, width) {
        var opt = options($object);
        opt.width = width;
        if (!opt.running) {
            $object.combogrid("hidePanel");
        }
        $object.combogrid("resize", width);
        isEdit($object, opt.isEdit);
    }

    function destroy($object) {
        var opt = options($object);
        var $new_obj = $($object.prop("outerHTML"));
        $new_obj.show();
        var id = $object.attr("id");
        $new_obj.removeAttr("id");
        $new_obj.removeClass("textbox-f");
        $new_obj.removeClass("combo-f");
        $new_obj.removeClass("combogrid-f");
        $object.before($new_obj);

        opt.toolbar.yqEditMenu("destroy");
        opt.toolbar.remove();
        $object.combogrid("destroy");

        $new_obj.attr("id", id);

        $object.removeData("combogrid_opt");
        $object.removeData("yqtype");
    }

    function init_combogrid($object) {
        var opt = options($object);

        var opt_dg = {
            fitColumns: false,
            striped: false,

            collapsible: false,
            idField: opt.keyId,
            textField: "displayMember",

            rownumbers: opt.rownumbers,
            singleSelect: true,

            editable: false,

            multiple: false,

            columns: [[
                { field: opt.keyId, title: 'ID', width: 80 },
                { field: opt.displayMember, title: 'Name', width: 200 }
            ]],
            data: [],
            fitColumns: false,
            icons: [{
                iconCls: 'yqwin-combo-btn-icon fa fa-times',
                handler: function (e) {
                    $object.combogrid("clear");
                }
            }, {
                iconCls: 'yqwin-combo-btn-icon fa fa-caret-down',
                handler: function (e) {
                    $object.combogrid("hidePanel");

                    e.preventDefault();
                    uppActionState($object, function (tf) {
                        if (tf) {
                            opt.toolbar.yqEditMenu("open", e);
                        }
                    });
                }
            }, {
                iconCls: 'yqwin-combo-btn-icon fa fa-search',
                handler: function (e) {
                    e.preventDefault();
                    opt.toolbar.yqEditMenu("open_seek", $object.combogrid("textbox"));
                }
            }],

            onLoadSuccess: function (data) {
                var $icon0 = $object.combogrid("getIcon", 0);
                var $icon3 = $object.combogrid("getIcon", 3);
                $icon0.before($icon3);

                if (!opt.afterBinding) {
                    opt.afterBinding = true;
                    init_columns($object);
                } else {
                    if (opt.isPage) {
                        var pager = $object.combogrid("grid").datagrid("getPager")
                        pager.pagination("options").onSelectPage = function (pageNo, pageSize) {
                            opt.pageSize = pageSize;
                            opt.pageNo = pageNo;
                            loadData($object);
                        };
                        pager.pagination('refresh', {	// change options and refresh pager bar information
                            total: data.recordCount,
                            pageNumber: data.pageNo,
                            pageSize: opt.pageSize,
                            pageList: opt.pageList
                        });
                    }

                    $object.combogrid("grid").datagrid("resize", {
                        width: opt.panelWidth - 4,
                        height: opt.panelHeight - 4
                    });

                    opt.afterSetdata.call($object, data);

                    if (!opt.onload) {
                        form_load($object);
                    } else {
                        isEdit($object, opt.isEdit);
                        resize($object, opt.width);
                    }

                    setValue($object, opt.defaultVal);

                    opt.running = false;
                }
            },

            onChange: function (newValue, oldValue) {
                if (newValue == "") {
                    newValue = null;
                }
                if (oldValue == "") {
                    oldValue = null;
                }

                var newRow = null;
                var oldRow = null;
                var rows = $object.combogrid("grid").datagrid("getRows");
                var newIndex = -1;
                var oldIndex = -1;
                for (let i = 0; i < rows.length; i++) {
                    if (!(newValue === null) && rows[i][opt.keyId] == newValue) {
                        newIndex = i;
                        newRow = $.extend({}, rows[i]);
                    }
                    if (!(oldValue === null) && rows[i][opt.keyId] == oldValue) {
                        oldIndex = i;
                        oldRow = $.extend({}, rows[i]);
                    }
                }

                var opts_ = $object.combogrid("grid").datagrid("options");
                //console.log("onChange", newIndex, oldIndex, opts_);
                opt.onChange.call($object, newValue, newRow, oldValue, oldRow);
            },
        };

        if (typeof opt.panelWidth != undefined) {
            opt_dg.panelWidth = opt.panelWidth;
        }
        if (typeof opt.panelHeight != undefined) {
            opt_dg.panelHeight = opt.panelHeight;
        }

        if (opt.isPage) {
            opt_dg.pagination = true;  //显示分页
            opt_dg.pageNumber = opt.pageNo;
            opt_dg.pageSize = opt.pageSize;
            opt_dg.pageList = opt.pageList;
        }

        $object.combogrid(opt_dg);
    }

    function isEdit($object, tf) {
        var opt = options($object);

        var $icon2 = $object.combogrid("getIcon", 2);
        var $icon3 = $object.combogrid("getIcon", 3);
        opt.isEdit = tf;
        var btn_mub = 4;
        if (opt.isEdit) {
            $icon2.show();
        } else {
            btn_mub--;
            $icon2.hide();
        }

        if (opt.isSeek) {
            $icon3.show();
        } else {
            btn_mub--;
            $icon3.hide();
        }

        var $text = $object.next().find(".textbox-text");
        $text.css({
            "margin": "0px " + (26 * btn_mub) + "px 0px 0px",
            "width": (opt.width - (26 * btn_mub)) + "px"
        });
    }

    function init_columns($object) {
        var opt = options($object);

        if (opt.titles.length > 0) {
            var columns = $.yqDgColumns.call($object, opt.titles);

            opt.beforeBindingTitle.call($object, columns,
                function (_columns) {
                    opt.columns = _columns;
                    init_menu($object)
                });
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.tempno
            };

            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.titles = $.yqFmUiTitle(res.titles);
                    var columns = $.yqDgColumns.call($object, opt.titles);

                    opt.beforeBindingTitle.call($object, columns,
                        function (_columns) {
                            opt.columns = _columns;
                            init_menu($object);
                        });
                }
                else {
                    console.log(res);
                    $.yqMessager("error", res.info + "[" + res.error + "]");
                }
            })
        }
    }

    function init_menu($object) {
        var opt = options($object);

        var $toolbar = $("<div></div>");
        opt.toolbar = $toolbar;
        $object.after($toolbar);

        $toolbar.yqEditMenu({
            type: 2,  //1(!=2或3)-顶部菜单，2-右键菜单，3-顶部+右键
            mini: false,
            copy: opt.defaultEdit && opt.copy,
            addroot: false,
            add: opt.defaultEdit && opt.add,
            upp: opt.defaultEdit && opt.upp,
            del: opt.defaultEdit && opt.del,
            save: false,
            isdel: opt.defaultEdit && opt.isdel,
            state: opt.defaultEdit && opt.state,
            state_field: opt.state_field,
            cut: false,

            move: opt.defaultEdit && opt.move,
            links: opt.editLinks,  //显示的链接菜单
            menus: opt.editMenus,  //显示在其它中的菜单
            width: opt.popMenuWidth,  //右键菜单第一层宽度

            titles: opt.titles,         //
            ddSeeks: "",      //下拉查询字段，字段名称
            isSimple: false,    //简单查询
            txtSeeks: "",    //简单查询字段，字段名称
            isSimpleDDLW: 100, //简单查询选择项目宽度
            isSimpleTxtW: 100, //简单查询输入值宽度

            isSeek: opt.isSeek,  //高级查询
            seekNo: opt.seekNo,  //查询模板编码

            afterBindingTitle: function () {
                if (opt.data.rows.length > 0) {
                    setData($object, opt.data)
                }
                else if (opt.loadData) {
                    loadData($object);
                }
                else {
                    form_load($object);
                }
            }, //标题绑定后
            onClick: function (action, params) {      //按钮点击事件，action为操作id
                btnAction($object, action, params);
            },
            onSeek: function (where) {           //查询
                //console.log("where", where);
                //seek($object, where);
            }
        });
    }

    //重新加载数据
    function reSeek($object) {
        var opt = options($object);
        opt.prewhere = "*";
        loadData($object);
    }

    //查询
    function seek($object, where) {
        var opt = options($object);
        if (opt.prewhere == where) {
            return;
        }

        opt.where = where;
        loadData($object);
    }

    //加载数据
    function loadData($object) {
        var opt = options($object);
        if ((!(opt.bindingKeyId === null) && opt.bindingValue === null) ||
            (!(opt.pKeyId === null) && opt.pKeyValue === null)) {
            if (!opt.onload) {
                setData($object, { rows: [] });
            }

            return;
        }

        if (opt.running) {
            return;
        }

        opt.running = true;
        opt.prewhere = opt.where;
        if (opt.where === null) {
            opt.where = "";
        }
        var l_where = opt.where;

        if (!(opt.addWhere === null) && opt.addWhere != "") {
            if (l_where == "") {
                l_where = opt.addWhere;
            } else {
                l_where = "(" + l_where + ") and (" + opt.addWhere + ")";
            }
        }

        var bindWhere = "";
        if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
            bindWhere = opt.bindingKeyId + " = '" + opt.bindingValue + "'";
        }
        if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
            bindWhere += (bindWhere == "" ? "" : " and ") + opt.pKeyId + "='" + opt.pKeyValue + "'";
        }

        if (bindWhere != "") {
            if (l_where == "") {
                l_where = bindWhere;
            } else {
                l_where = "(" + l_where + ") and (" + bindWhere + ")";
            }
        }

        $object.combogrid("grid").datagrid("loading");

        if (opt.isPage) {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,
                tbname: opt.tbname,
                where: l_where,
                order: opt.order,
                pagesize: opt.pageSize,
                pageno: opt.pageNo
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            opt.beforeLoadData.call($object, pp_opt, function (_pp_opt, _data) {
                if (_data === null) {
                    $.yqDbTbPaging(_pp_opt, function (data) {
                        if (data.error == 0) {
                            setData($object, data)
                        }
                        else {
                            opt.running = false;
                            $object.combogrid("grid").datagrid("loaded");
                            if (!opt.onload) {
                                form_load($object);
                            }
                        }
                    });
                } else {
                    if (_data.error == 0) {
                        setData($object, _data)
                    }
                    else {
                        opt.running = false;
                        $object.combogrid("grid").datagrid("loaded");
                        if (!opt.onload) {
                            form_load($object);
                        }
                    }
                }
            });
        }
        else {
            pp_opt = {
                url: opt.ajaxUrl,
                dbname: opt.dbname,
                tbname: opt.tbname,
                where: l_where,
                order: opt.order
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            opt.beforeLoadData.call($object, pp_opt, function (_pp_opt, _data) {
                if (_data === null) {
                    $.yqDbTbSelect(_pp_opt, function (data) {
                        if (data.error == 0) {
                            setData($object, data)
                        }
                        else {
                            opt.running = false;
                            $object.combogrid("grid").datagrid("loaded");
                            if (!opt.onload) {
                                form_load($object);
                            }
                        }
                    });
                } else {
                    if (_data.error == 0) {
                        setData($object, _data)
                    }
                    else {
                        opt.running = false;
                        $object.combogrid("grid").datagrid("loaded");
                        if (!opt.onload) {
                            form_load($object);
                        }
                    }
                }
            });
        }
    }

    function setData($object, data) {
        var opt = options($object);
        opt.running = true;
        $object.combogrid("grid").datagrid("loading");

        data.rows = $.yqFmToViews(data.rows, opt.titles);

        for (var i = 0; i < data.rows.length; i++) {
            data.rows[i]["displayMember"] = $.getDisplayValue(data.rows[i], opt.displayMember);
        }

        setForienKeys($object, data.rows,
            function () {
                opt.beforeSetdata.call($object, data, function (_data) {
                    opt.data = _data;

                    var data_ = $.extend({}, _data);
                    var rows_ = [];
                    _data.rows.forEach(row => {
                        rows_.push($.extend({}, row))
                    });
                    data_.rows = rows_;

                    if (opt.isPage) {
                        $object.combogrid("grid").datagrid("options").pageNumber = data_.pageNo;
                    }

                    $object.combogrid({
                        columns: opt.columns,
                        data: data_,
                    });
                });
            });
    }

    //外键处理
    function setForienKeys($object, rows, callback) {
        var opt = options($object);
        var opts = {
            "ajaxUrl": opt.ajaxUrl,
            "rows": rows,
            "titles": opt.titles,
            "fk_rows": opt.fk_rows === undefined ? [] : opt.fk_rows
        };

        if (typeof opt._appno != undefined) {
            opts.ctrlid = opt._ctrlid;
            opts.appno = opt._appno;
            opts.menuno = opt._menuno;
        }

        $.yqGetForeignkeys(opts,
            function (fk_rows) {
                opt.fk_rows = fk_rows;
                callback();
            });
    }

    //更新操作状态信息
    function uppActionState($object, callback) {
        var opt = options($object);
        var value = $object.combogrid("getValue");
        var row = $object.combogrid("grid").datagrid("getSelected");

        if (!(opt.bindingKeyId === null) && opt.bindingValue === null) {
            if (opt.copy) {
                opt.toolbar.yqEditMenu("disable", "copy");
            }
            if (opt.add) {
                opt.toolbar.yqEditMenu("disable", "add");
            }
            if (opt.upp) {
                opt.toolbar.yqEditMenu("disable", "upp");
            }
            if (opt.del) {
                opt.toolbar.yqEditMenu("disable", "del");
            }
            if (opt.isdel) {
                opt.toolbar.yqEditMenu("disable", "isdel1");
                opt.toolbar.yqEditMenu("disable", "isdel0");
            }
            if (opt.state) {
                opt.toolbar.yqEditMenu("disable", "state");
            }
            if (opt.move) {
                opt.toolbar.yqEditMenu("disable", "move");
            }

            opt.uppActionState.call($object, value, row, function (tf) {     //操作节点状态处理接口
                if (callback) {
                    callback(tf);
                }
            });

            return;
        }

        var is_edit = opt.isEdit;
        if (is_edit && !(row === null) && opt.wflock) {
            if (row["wflock"]) {
                is_edit = false;
            }
        }

        //todo 按钮处理
        if (opt.copy) {
            opt.toolbar.yqEditMenu(((is_edit == false || row === null) ? "disable" : "enable"), "copy");
        }

        if (opt.add) {
            opt.toolbar.yqEditMenu((is_edit == false ? "disable" : "enable"), "add");
        }

        if (opt.upp) {
            opt.toolbar.yqEditMenu((row === null ? "disable" : "enable"), "upp");
        }

        if (opt.del) {
            var del = false;
            if (!(row === null)) {
                if (opt.isdel && opt.isdelEdit == false) {
                    if (row[opt.isdel_field] === undefined ||
                        row[opt.isdel_field] === null ||
                        row[opt.isdel_field] == false) {
                        del = true;
                    }
                }
                else {
                    del = true;
                }
            }

            opt.toolbar.yqEditMenu(((is_edit == false || del == false) ? "disable" : "enable"), "del");
        }

        if (opt.isdel) {
            var isdel1 = false;
            var isdel0 = false;
            if (!(row === null)) {
                if (row[opt.isdel_field] === undefined ||
                    row[opt.isdel_field] === null) {
                    isdel1 = true;
                } else {
                    if (row[opt.isdel_field]) {
                        isdel0 = true;
                    }
                    else {
                        isdel1 = true;
                    }
                }
            }

            opt.toolbar.yqEditMenu(((is_edit == false || isdel1 == false) ? "disable" : "enable"), "isdel1");
            opt.toolbar.yqEditMenu(((is_edit == false || isdel0 == false) ? "disable" : "enable"), "isdel0");
        }

        if (opt.state) {
            if (row === null || !is_edit) {
                opt.toolbar.yqEditMenu("disable", "state");
            }
            else {
                var state_value = row[opt.state_field];
                var state_lists = [];
                for (var i = 0; i < opt.titles.length; i++) {
                    if (opt.titles[i].name == opt.state_field) {
                        state_lists = opt.titles[i].ui_mask.lists;
                        break;
                    }
                }
                if (state_lists === undefined) {
                    state_lists = [];
                }
                opt.toolbar.yqEditMenu((state_lists.length == 0 ? "disable" : "enable"), "state");
                for (var i = 0; i < state_lists.length; i++) {
                    opt.toolbar.yqEditMenu((state_value == state_lists[i].no ? "disable" : "enable"), "state_" + state_lists[i].no);
                }
            }
        }

        if (opt.move) {
            var move = false;
            var rows = $object.combogrid("grid").datagrid("getRows");
            if (rows.length > 1) {
                move = true;
            }
            opt.toolbar.yqEditMenu(((is_edit == false || move == false) ? "disable" : "enable"), "move");
        }

        opt.uppActionState.call($object, value, row, function (tf) {     //操作节点状态处理接口
            if (callback) {
                callback(tf);
            }
        });
    }

    function btnAction($object, action, params) {
        var opt = options($object);

        if (params === undefined) {
            params = {};
        }

        opt.btnAction.call($object, action, params,
            function (tf) {
                if (tf) {
                    opt.innerEdit_ = true;
                    const actionHandlers = {
                        "copy": copy,
                        "add": add,
                        "upp": upp,
                        "del": del,
                        "isdel1": (obj) => isdel(obj, true),
                        "isdel0": (obj) => isdel(obj, false),
                        "state": (obj) => state(obj, params),
                        "move": move,
                        // "toexcel": toexcel,
                        // "inexcel": inexcel
                    };

                    if (action in actionHandlers) {
                        actionHandlers[action]($object);
                    } else {
                        console.warn("未知的操作: ", action); // 添加默认处理逻辑
                    }
                }
            });
    }

    function copy($object) {
        var opt = options($object);
        var row = $object.combogrid("grid").datagrid("getSelected");
        var _row = $.extend({}, row);
        delete _row[opt.keyId];
        showEdit($object, "add", _row);
    }

    function add($object) {
        var opt = options($object);
        _row = {};
        if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
            _row[opt.bindingKeyId] = opt.bindingValue;
        }
        if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
            _row[opt.pKeyId] = opt.pKeyValue;
        }
        showEdit($object, "add", _row);
    }

    function upp($object) {
        var opt = options($object);
        var row = $object.combogrid("grid").datagrid("getSelected");
        var _row = $.extend({}, row);
        showEdit($object, "upp", _row);
    }

    function showEdit($object, action, row) {
        var opt = options($object);

        var pp = $object.combogrid("textbox");
        prevent_e = $.getPreventDefault(pp[0]);

        // var prevent_e = $.getPreventDefault($object[0]);
        // if (window.top == window.self) {
        //     prevent_e.clientX += 4;
        //     prevent_e.clientY += 32;
        // } else {
        //     prevent_e.clientX -= 5;
        //     prevent_e.clientY += 23;
        // }

        prevent_e.id = $object.attr("id");
        prevent_e.options = opt;
        var mdiinfo = $.yqGetWindParams();

        if (opt.editMode == 1 ||
            opt.editMode == 2 ||
            opt.editMode == 3) {
            if (opt.editType == 1) {
                getEditTitles($object, function (titles) {
                    opt.onBeforeShowEdit.call($object, titles, action, row, function (tf, _titles, _row) {
                        if (tf) {
                            var run_opt = {
                                ajaxUrl: opt.ajaxUrl,
                                mdiinfo: mdiinfo,
                                prevent_e: prevent_e,
                                width: opt.editModeW,
                                height: opt.editModeH,
                                titles: _titles,
                                action: action,
                                row: _row,
                                isEdit: opt.isEdit,

                                loadDefault: opt.loadDefault,   //加载默认值
                                blankTag: opt.blankTag,        //值不能为空，标题附加标记

                                width: opt.editModeW,
                                height: opt.editModeH,

                                dbname: opt.dbname,

                                callback: function (row_) {
                                    showEditAfter($object, action, row_);
                                }
                            };
                            if (window.top == window.self) {
                                $.yqAttrPopEdit(run_opt);
                            }
                            else {
                                window.top.$.yqAttrPopEdit(run_opt);
                            }
                        }
                    });
                });
            } else if (opt.editType == 2) {
                getEditModel($object, function (titles, model) {
                    opt.onBeforeShowEdit.call($object, titles, action, row, function (tf, _titles, _row) {
                        if (tf) {
                            var run_opt = {
                                mdiinfo: mdiinfo,
                                prevent_e: prevent_e,

                                ajaxUrl: opt.ajaxUrl,
                                titles: _titles,
                                model: model,
                                action: action,
                                row: _row,
                                isEdit: opt.isEdit,

                                loadDefault: opt.loadDefault,   //加载默认值
                                blankTag: opt.blankTag,        //值不能为空，标题附加标记

                                width: opt.editModeW,
                                height: opt.editModeH,

                                dbname: opt.dbname,

                                callback: function (row_) {
                                    showEditAfter($object, action, row_);
                                }
                            };

                            if (window.top == window.self) {
                                $.yqFormPopEdit(run_opt);
                            }
                            else {
                                window.top.$.yqFormPopEdit(run_opt);
                            }

                        }
                    });


                });

            }
        } else if (opt.editMode == 4) {
            opt.onBeforeShowEdit.call($object, opt.titles, action, row, function (tf, _titles, _row) {
                if (tf) {
                    if (opt.$row === undefined) {
                        getEditModel($object, function (titles, model) {
                            showEditModel(_row, titles, model);
                        });
                    } else {
                        var s_row = $.extend({}, opt.$row);
                        delete opt.$row;
                        showEditModel(s_row);
                    }
                }
            });
        }

        function showEditModel(row, titles, model) {
            prevent_e.p_target = $object;

            if (!(model === undefined)) {
                prevent_e.titles = titles;
                prevent_e.model = model;
                prevent_e.dbname = opt.dbname;
            }
            prevent_e.action = action;
            prevent_e.row = row;
            if (!(opt.$type === undefined)) {
                prevent_e.type = opt.$type;
                delete opt.$type;
            }

            var editUrl = opt.editUrl;
            if ($.urlParam(editUrl, "appno") == "") {
                var appno = $.urlRequest("appno");
                if (appno != "") {
                    var menuno = $.urlRequest("menuno");
                    editUrl += (editUrl.indexOf("?") == -1 ? "?" : "&") + "appno=" + appno + "&menuno=" + menuno;
                }
            }

            var edit_pops = {
                prevent_e: prevent_e,
                mdiinfo: mdiinfo,
                title: opt.editTitle,
                width: opt.editModeW,
                height: opt.editModeH,
                maximiz: opt.editMaximiz,
                url: editUrl,

                onOpen: function () {
                    //console.log("onOpen");
                },
                onBeforeClose: function () {
                    //console.log("onBeforeClose");
                    return true;
                },
            };

            if (window.top == window.self) {
                $.yqWinPopEdit(edit_pops);
            }
            else {
                window.top.$.yqWinPopEdit(edit_pops);
            }
        }
    }

    function showEditAfter($object, action, row_) {
        var opt = options($object);
        if (action == "add") {
            delete row_[opt.keyId];

            if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                row_[opt.bindingKeyId] = opt.bindingValue;
            }
            if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
                row_[opt.pKeyId] = opt.pKeyValue;
            }
        }
        var row_ = $.yqFmToData(row_, opt.titles);

        var d_rows = [];
        var m_row = {
            action: action,
            row: row_
        }
        d_rows.push(m_row);
        dataAction($object, d_rows);
    }

    function rowEdit($object, action, row) {
        var opt = options($object);

        if (action == "add") {
            delete row[opt.keyId];

            if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                row[opt.bindingKeyId] = opt.bindingValue;
            }
            if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
                row[opt.pKeyId] = opt.pKeyValue;
            }
        }

        var d_rows = [];
        var m_row = {
            action: action,
            row: row
        }
        d_rows.push(m_row);
        dataAction($object, d_rows);
    }

    function getEditTitles($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_titles != "undefined") {
            callback(opt.edit_titles);
        }
        else if (opt.tempno == opt.editModeNo) {
            opt.edit_titles = opt.titles;
            callback(opt.edit_titles);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.editModeNo
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    //console.log(res);
                    opt.edit_titles = opt.titles;
                }

                callback(opt.edit_titles);
            })
        }
    }

    //form编辑模式 begin
    function getEditModel($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_titles != "undefined") {
            getEditModel_($object, function (model) {
                callback(opt.edit_titles, model);
            });
        }
        else if (opt.tempno == -1) {
            opt.edit_titles = opt.titles;
            getEditModel_($object, function (model) {
                callback(opt.edit_titles, model);
            });
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: -1
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    //console.log(res);
                    opt.edit_titles = opt.titles;
                }

                getEditModel_($object, function (model) {
                    callback(opt.edit_titles, model);
                });
            })
        }
    }

    function getEditModel_($object, callback) {
        var opt = options($object);
        if (typeof opt.edit_model != "undefined") {
            callback(opt.edit_model);
        }
        else if (opt.tempno == opt.editModeNo) {
            opt.edit_model = JSON.stringify(opt.titles);
            callback(opt.edit_model);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.editModeNo
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbModel(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.edit_model = res.model;
                } else {
                    //console.log(res);
                    opt.edit_model = JSON.stringify(opt.titles);
                }

                callback(opt.edit_model);
            })
        }
    }
    //form编辑模式  end


    function del($object) {
        var opt = options($object);
        var row = $object.combogrid("grid").datagrid("getSelected");
        if (row === null) {
            return;
        }

        del_run($object, row);
    }

    function del_run($object, row) {
        var opt = options($object);
        var d_rows = [];
        var _row = {};
        _row[opt.keyId] = row[opt.keyId];
        var m_row = {
            action: "del",
            row: _row
        }
        d_rows.push(m_row);

        if (opt.editAlert && opt.innerEdit_) {
            $.yqConfirm("删除", "是否确认?",
                function (r) {
                    if (r) {
                        dataAction($object, d_rows);
                    }
                });
        } else {
            dataAction($object, d_rows);
        }
    }

    function isdel($object, tf) {
        var opt = options($object);
        var row = $object.combogrid("grid").datagrid("getSelected");
        if (row === null) {
            return;
        }

        var d_rows = [];
        var _row = {};
        _row[opt.keyId] = row[opt.keyId];
        _row[opt.isdel_field] = tf;
        var m_row = {
            action: "upp_",
            row: _row
        }
        d_rows.push(m_row);
        dataAction($object, d_rows);
    }

    function move($object) {
        var opt = options($object);
        var rows = $object.combogrid("grid").datagrid("getRows");
        if (rows.length == 0) {
            return;
        }
        getMoveTitles($object, function (titles) {
            opt.onBeforeShowEdit.call($object, titles, "move", rows,
                function (tf, _titles, _rows) {
                    if (tf) {
                        var opt = options($object);
                        var prevent_e = $.getPreventDefault($object[0]);
                        prevent_e.clientX += 8;
                        prevent_e.clientY += 43;

                        prevent_e.id = $object.attr("id");
                        prevent_e.options = opt;

                        var mdiinfo = $.yqGetWindParams();
                        var run_opt = {
                            ajaxUrl: opt.ajaxUrl,
                            mdiinfo: mdiinfo,
                            prevent_e: prevent_e,
                            width: opt.seekModeW,
                            height: opt.seekModeH,
                            titles: _titles,
                            rows: _rows,
                            callback: function (rows_) {
                                var d_rows = [];
                                var ids = [];
                                var ids_ = [];
                                for (var i = 0; i < rows_.length; i++) {
                                    ids.push(rows_[i][opt.keyId]);
                                }

                                for (var j = 0; j < rows.length; j++) {
                                    ids_.push(rows[j][opt.keyId]);
                                }

                                if (JSON.stringify(ids) == JSON.stringify(ids_)) {
                                    return;
                                }

                                var m_row = {
                                    "action": "move",
                                    "row":
                                    {
                                        "ids": ids
                                    }
                                }
                                if (!(opt.bindingKeyId === null) && !(opt.bindingValue === null)) {
                                    m_row.row["binding_field"] = opt.bindingKeyId;
                                    m_row.row[opt.bindingKeyId] = opt.bindingValue;
                                }
                                if (!(opt.pKeyId === null) && !(opt.pKeyValue === null)) {
                                    m_row.row["pid_field"] = opt.pKeyId;
                                    m_row.row[opt.pKeyId] = opt.pKeyValue;
                                }
                                d_rows.push(m_row);
                                dataAction($object, d_rows);

                            }
                        };
                        if (window.top == window.self) {
                            $.yqRowsPopMove(run_opt);
                        }
                        else {
                            window.top.$.yqRowsPopMove(run_opt);
                        }
                    }
                });
        });
    }

    function state($object, params) {
        var opt = options($object);
        var s_row = $object.combogrid("grid").datagrid("getSelected");
        if (s_row === null) {
            return;
        }

        var row = {};
        row[opt.keyId] = s_row[opt.keyId];
        row[opt.state_field] = params.no;
        var d_rows = [{
            "action": "upp_",
            "row": row
        }];
        dataAction($object, d_rows);
    }

    //取得移动编辑模板
    function getMoveTitles($object, callback) {
        var opt = options($object);
        if (typeof opt.move_titles != "undefined") {
            callback(opt.move_titles);
        }
        else if (opt.tempno == opt.moveModeNo) {
            opt.move_titles = opt.titles;
            callback(opt.move_titles);
        }
        else {
            var pp_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                tempno: opt.moveModeNo
            };
            if (typeof opt._appno != undefined) {
                pp_opt.ctrlid = opt._ctrlid;
                pp_opt.appno = opt._appno;
                pp_opt.menuno = opt._menuno;
            }

            $.yqTbTitle(pp_opt, function (res) {
                if (res.error == 0) {
                    opt.move_titles = $.yqFmUiTitle(res.titles);
                }
                else {
                    //console.log(res);
                    opt.move_titles = opt.titles;
                }

                callback(opt.move_titles);
            })
        }
    }

    function dataAction($object, rows) {
        var opt = options($object);
        //$.yqFmToData(rows[i], opt.titles)
        var a_rows = [];
        for (var i = 0; i < rows.length; i++) {
            var _row = { action: rows[i].action };
            if (rows[i].action == "add" || rows[i].action == "upp") {
                _row.row = $.yqFmToData(rows[i].row, opt.titles);
            }
            else {
                _row.row = rows[i].row;
            }

            a_rows.push(_row);
        }

        opt.beforeDataAction.call($object, a_rows,
            function (tf, _a_rows) {
                if (tf) {
                    var file_titles = getFile_edit_titles();
                    //保存前，文件上传处理
                    if (file_titles.length > 0) {
                        $.yqFilesUpload(file_titles, _a_rows, function (__a_rows) {
                            for (let jj = 0; jj < __a_rows.length; jj++) {
                                for (let ii = 0; ii < file_titles.length; ii++) {
                                    rows[jj].row[file_titles[ii].field_name] = __a_rows[jj].row[file_titles[ii].field_name];
                                }
                            }

                            toDB(__a_rows, file_titles);
                        })
                    } else {
                        toDB(_a_rows, null);
                    }
                }
            });

        //获取文件字段
        function getFile_edit_titles() {
            if (opt.f_edit_titles === undefined) {
                //文件处理
                opt.f_edit_titles = [];
                if (typeof opt.edit_titles === "object") {
                    for (let i = 0; i < opt.edit_titles.length; i++) {
                        if (opt.edit_titles[i].ui_type == 18 ||
                            opt.edit_titles[i].ui_type == 19) {
                            opt.f_edit_titles.push({
                                field_type: opt.edit_titles[i].ui_type,
                                field_name: opt.edit_titles[i].name,
                                sto_type: opt.edit_titles[i].ui_mask.storageType,
                                sto_name: (opt.edit_titles[i].ui_mask.storageType == 1 ? opt.dbname : opt.edit_titles[i].ui_mask.storageName),
                                chunk: opt.edit_titles[i].ui_mask.chunk
                            });
                        }
                    }
                } else {
                    for (let i = 0; i < opt.titles.length; i++) {
                        if (opt.titles[i].ui_type == 18 ||
                            opt.titles[i].ui_type == 19) {
                            opt.f_edit_titles.push({
                                field_type: opt.titles[i].ui_type,
                                field_name: opt.titles[i].name,
                                sto_type: opt.titles[i].ui_mask.storageType,
                                sto_name: (opt.titles[i].ui_mask.storageType == 1 ? opt.dbname : opt.titles[i].ui_mask.storageName),
                                chunk: opt.titles[i].ui_mask.chunk
                            });
                        }
                    }
                }
            }

            return opt.f_edit_titles;
        }

        function toDB(a_rows, file_params) {
            var a_opt = {
                ajaxUrl: opt.ajaxUrl,
                dbname: opt.dbname,                //数据库
                tbname: opt.tbname,                //表
                rows: a_rows,
            };

            if (typeof opt._appno != undefined) {
                a_opt.ctrlid = opt._ctrlid;
                a_opt.appno = opt._appno;
                a_opt.menuno = opt._menuno;
            }

            if (typeof file_params == "object") {
                a_opt.fileparm = file_params;
            }

            $.yqDbAction(a_opt,
                function (res) {
                    dataAction_($object, rows, res);
                });
        }
    }

    function dataAction_($object, rows, res) {
        var opt = options($object);

        if (res.error == 0) {
            var error = "";
            if (res.rows[0].error == 0) {
                if (res.rows[0].action == "add") {
                    rows[0].row[opt.keyId] = res.rows[0][opt.keyId];
                    appendRow_data($object, rows[0].row);

                    if (opt.editLoadData) {
                        editLoadData($object, rows[0].row[opt.keyId]);
                    }
                }
                else if (res.rows[0].action == "del") {
                    deleteRow_data($object, rows[0].row);
                }
                else if (res.rows[0].action == "move") {
                    moveRow_data($object, rows[0].row);
                }
                else {
                    updateRow_data($object, rows[0].row);

                    if (opt.editLoadData) {
                        editLoadData($object, rows[0].row[opt.keyId]);
                    }
                }
            } else {
                error += res.rows[0].info + "[" + res.rows[0].error + "]";
            }

            if (error != "") {
                $.yqMessager("error", error);
                if (rows[0].action == "add" ||
                    rows[0].action == "upp") {
                    showEdit($object, rows[0].action, rows[0].row);
                }
            } else {
                $.yqMessager("success", "执行成功。");

            }
        }
        else {
            $.yqMessager("error", res.info + "[" + res.error + "]");
        }

        opt.afterDataAction.call($object, rows, res);
    }

    function editLoadData($object, sid) {
        var opt = options($object);
        var opt_row = {
            ajaxUrl: opt.ajaxUrl,
            dbname: opt.dbname,                //数据库
            tbname: opt.tbname,                       //表
            keyid: opt.keyId,
            keyval: sid
        };
        if (typeof opt._appno != undefined) {
            opt_row.ctrlid = opt._ctrlid;
            opt_row.appno = opt._appno;
            opt_row.menuno = opt._menuno;
        }

        $.yqDbTbRow(opt_row, function (res) {
            if (res.error == 0) {
                updateRow_data($object, res.row);
            } else {
                console.log(res);
            }
        })
    }

    function appendRow_data($object, row) {
        var opt = options($object);
        var _row = $.yqFmToView(row, opt.titles);
        _row["displayMember"] = $.getDisplayValue(_row, opt.displayMember);

        var opt = options($object);
        $object.combogrid("grid").datagrid('appendRow', _row);

        if (opt.isPage) {
            var pager = $object.combogrid("grid").datagrid('getPager');
            pager.pagination('refresh', {
                total: opt.data.recordCount,
                pageNumber: opt.data.pageNo
            });
        }

        $object.combogrid("grid").datagrid('selectRow',
            ($object.combogrid("grid").datagrid('getRows').length - 1));
    }

    function updateRow_data($object, row) {
        var opt = options($object);
        var rows = $object.combogrid("grid").datagrid("getRows");
        for (var i = 0; i < rows.length; i++) {
            if (row[opt.keyId] == rows[i][opt.keyId]) {
                var _row = $.extend(rows[i], row);
                _row["displayMember"] = $.getDisplayValue(_row, opt.displayMember);
                updateRow_data_($object, _row, i);
                break;
            }
        }
    }

    function updateRow_data_($object, row, index) {
        var opt = options($object);

        var rows = $object.combogrid("grid").datagrid("getRows");
        var oldRow = $.extend({}, rows[index]);

        var _row = $.yqFmToView(row, opt.titles);
        _row["displayMember"] = $.getDisplayValue(_row, opt.displayMember);
        $object.combogrid("grid").datagrid("updateRow", { index: index, row: _row });
        $object.combogrid("grid").datagrid('refreshRow', index);
        $object.combogrid("grid").datagrid('selectRow', index);

        opt.onChange.call($object, index, _row, index, oldRow);
    }

    function moveRow_data($object, row) {
        var opt = options($object);
        var _row = $object.combogrid("grid").datagrid("getSelected");
        var _rows = $object.combogrid("grid").datagrid("getRows");
        var rows = [];
        var index = -1;
        for (var i = 0; i < row.ids.length; i++) {
            if (!(_row === null)) {
                if (row.ids[i] == _row[opt.keyId]) {
                    index = i;
                }
            }

            for (var j = 0; j < _rows.length; j++) {
                if (row.ids[i] == _rows[j][opt.keyId]) {
                    _rows[j]["queue"] = (i + 1);
                    rows.push(_rows[j]);
                    break;
                }
            }
        }

        $object.combogrid("grid").datagrid("loadData", { rows: rows });
        if (index != -1) {
            $object.combogrid("grid").datagrid('selectRow', index);
        }
    }

    //todata
    function deleteRow_data($object, row) {
        var opt = options($object);
        var _rows = $object.combogrid("grid").datagrid("getRows");
        var i = 0;
        for (i = 0; i < _rows.length; i++) {
            if (row[opt.keyId] == _rows[i][opt.keyId]) {
                break;
            }
        }

        deleteRow_data_($object, i)
    }

    function deleteRow_data_($object, i) {
        var opt = options($object);
        $object.combogrid("grid").datagrid("deleteRow", i);

        if (i < $object.combogrid("grid").datagrid("getRows").length) {
            $object.combogrid("grid").datagrid('selectRow', i);
        }
        else {
            $object.combogrid("clear");
        }
    }

    function getValue($object) {
        var opt = options($object);
        return $object.combogrid("getValue");
    }

    function setValue($object, value) {
        var opt = $object.data("combogrid_opt");

        if (!opt.onload) {
            setTimeout(function () {
                setValue($object, value);
            }, 500);

            return;
        }

        if (value === undefined || value === null || value == "") {
            opt.defaultVal = null;
            $object.combogrid("clear");
            return;
        }

        opt.defaultVal = value;

        var rows = $object.combogrid("grid").datagrid('getRows');
        var selected = false;
        for (let i = 0; i < rows.length; i++) {
            if (value == rows[i][opt.keyId]) {
                selected = true;
                $object.combogrid("grid").datagrid('selectRow', i);
                break;
            }
        }
        if (selected) {
            return;
        }

        //数据库拉取值。。。
        var options = {
            ajaxUrl: opt.ajaxUrl,
            dbname: opt.dbname,                //数据库
            tbname: opt.tbname,                       //表
            keyid: opt.keyId,
            keyval: value
        };

        $.yqDbTbRow(options, function (res) {
            if (res.error == 0) {
                setForienKeys($object, { rows: [res.row] },
                    function () {
                        opt.beforeSetdata.call($object, { rows: [row] }, function (_data) {
                            var row_ = $.extend({}, _data.rows[0]);
                            $object.combogrid("grid").datagrid("appendRow", row_);
                            $object.combogrid("grid").datagrid('selectRow',
                                $object.combogrid("grid").datagrid('getRows').length - 1);
                        });
                    });
            }
            else {
                alert(res.info);
            }
        });
    }

    function getSelected($object) {
        return $object.combogrid("grid").datagrid('getSelected');
    }

    function setSelected($object, row) {
        var opt = options($object);
        if (!opt.onload) {
            setTimeout(function () {
                setSelected($object, row);
            }, 500);

            return;
        }

        if (value === undefined || value === null || value == "") {
            $object.combogrid("clear");
            return;
        }

        var rows = $object.combogrid("grid").datagrid('getRows');
        var selected = false;
        for (let i = 0; i < rows.length; i++) {
            if (row[opt.keyId] == rows[i][opt.keyId]) {
                selected = true;
                $object.combogrid("grid").datagrid('selectRow', i);
                break;
            }
        }
        if (selected) {
            return;
        }

        row = $.yqFmToView(row, opt.titles);

        setForienKeys($object, { rows: [row] },
            function () {
                opt.beforeSetdata.call($object, { rows: [row] }, function (_data) {
                    var row_ = $.extend({}, _data.rows[0]);
                    $object.combogrid("grid").datagrid("appendRow", row_);
                    $object.combogrid("grid").datagrid('selectRow',
                        $object.combogrid("grid").datagrid('getRows').length - 1);
                });
            });
    }
})(jQuery);
